package org.kalai.unifypay.servlet;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.kalai.unifypay.SessionManager;
import org.kalai.unifypay.bean.Bizcnf;
import org.kalai.unifypay.bean.Member;
import org.kalai.unifypay.bean.Transflow;
import org.kalai.unifypay.util.CommonUtil;
import org.kalai.unifypay.util.DataDao;
import org.kalai.unifypay.util.PropertiesUtil;
import org.kalai.unifypay.util.ProxyPayUtil;

import com.alibaba.fastjson.JSON;
import com.lechinepay.channel.chanpay.gateway.Gateway;

/**
 * 畅捷快捷支付异步通知
 */
@WebServlet("/CJQuickPaymentNotify")
public class CJQuickPaymentNotify extends HttpServlet {

   private static final Logger logger              = Logger.getLogger(CJQuickPaymentNotify.class);

   private static final long   serialVersionUID    = 1L;

   /**
    * 平台公钥
    */
   private static String       MERCHANT_PUBLIC_KEY = PropertiesUtil.getProperties("CJ_MERCHANT_PUBLIC_KEY");

   /**
    * @see HttpServlet#HttpServlet()
    */
   public CJQuickPaymentNotify() {
      super();
      // TODO Auto-generated constructor stub
   }

   /**
    * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
    *      response)
    */
   protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      // TODO Auto-generated method stub
   }

   /**
    * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
    *      response)
    */
   protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

      Map<String, Object> requestMap =new HashMap<String, Object>(CommonUtil.getRequestParams(request,"UTF-8"));
      String tranxSN = requestMap.get("outer_trade_no").toString();
      try {
         boolean verifyResult = Gateway.verify(requestMap, MERCHANT_PUBLIC_KEY);
         if (!verifyResult) {
            throw new RuntimeException("验签失败");
         }
         // 查询订单信息
         Transflow transflow = DataDao.getInstance().getTransflow(tranxSN);
         if (transflow == null)
            throw new RuntimeException("订单查询为空");

         new CJQuickPaymentNotify().notifyManage(transflow, requestMap);

      } catch (Exception e) {
         logger.error(String.format("(畅捷)快捷支付异步通知异常:参数[requestMap=%s],异常详情:%s", requestMap, e));
      } finally {
         logger.info("(畅捷)快捷支付异步通知成功:" + tranxSN);
         CommonUtil.responseObject(response, "success");
      }
   }

   /**
    * 处理异步通知
    * 
    * @param transflow
    * @param params
    * @throws Exception
    */
   public void notifyManage(Transflow transflow, Map<String, Object> params) throws Exception {
      if (transflow == null)
         throw new RuntimeException(String.format("交易订单为空,接收畅捷参数:%s", params));

      /* 支付中的订单才进行处理 */
      if (transflow.getStatus() == 1) {

         /* 查询商户信息是否存在 */
         Member member = DataDao.getInstance().getMember(transflow.getMemberNo());
         if (member == null)
            throw new RuntimeException("商户信息不存在:" + transflow.getMemberNo());

         /* 畅捷收到的交易金额 */
         Double tradeAmount = 0.0;
         if (params.get("trade_amount") != null) {
            tradeAmount = Double.valueOf((String) params.get("trade_amount"));
         }
         /* 畅捷交易状态 */
         String status = (String) params.get("trade_status");
         String respCode="02";
         switch (status) {
         case "TRADE_SUCCESS":
            /*交易成功*/
            respCode="00";
            break;
         case "TRADE_FINISHED":
            /*交易结束*/
            respCode="00";
            break;
         default:
            respCode="02";
            break;
         }
         /* 更新交易表 */
         boolean isok = "00".equals(respCode);
         DataDao.getInstance().updateTransflow(transflow.getTranxSN(), "", tradeAmount.longValue(), isok ? 2 : 3,
               respCode, isok ? "交易成功" : "畅捷没有失败通知");

         /* D0交易成功后实时代付出去 */
         String bizcode = transflow.getBizcode();
         Bizcnf bizcnf = DataDao.getInstance().getBizcnfByCode(bizcode);
         if (isok && bizcnf.getPattern() == 0) {
            String settNo = CommonUtil.generSettNo();
            boolean rs = DataDao.getInstance().addSettlement(transflow.getTranxSN(), settNo, bizcode, member,
                  transflow.getTransAmt() - transflow.getTransFee(), 1);
            if (rs)
               ProxyPayUtil.proxyPay(settNo, member,
                     ((Double) (transflow.getTransAmt() * 100 - transflow.getTransFee() * 100)).longValue(), bizcode, true);
         }
         // 异步通知账单系统
         CommonUtil.notifyTransFlow(transflow);
         /* 异步通知合作方 */
         String url = transflow.getNotifyUrl();
         String partnerCode = transflow.getPartnerCode();
         String secret = DataDao.getInstance().getPartnerByCode(partnerCode).getPartnerSecret();
         if (url != null && !"".equals(url))
            CommonUtil.notifyMessage(url, partnerCode, secret, transflow.getTranxSN(), transflow.getOrderNo(),
                  transflow.getTransAmt(), respCode, "异步通知成功");

         /* websocket推送消息 */
         Map<String, Object> result = CommonUtil.createRespMap(respCode, "异步通知成功");
         SessionManager.getInstance().broadcast(transflow.getTranxSN(), JSON.toJSONString(result));
      } else {
         throw new RuntimeException(transflow.getTranxSN() + "订单状态异常:status=" + transflow.getStatus());
      }
   }
}
